package com.zeyuan.rpcclient.netty.HandlerAndPipeline;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class Handler {
    /*channelhandler用于处理channel上各种事件，分为出站入站两种，所有channelhandler连成一串就是pipeline
    入站处理器是channelinboundhandleradapter的子类，用于读取客户端数据写回结果
    出站处理器是channeloutboundhandleradapter的子类，用于对写回结果进行加工
    *
    * */
    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        //通过channel拿到pipeline
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                        //添加处理器 初始化pipeline的时候会有默认head和tail
                        //pipeline: head->handler1->2->3->4->tail
                        //入站处理器发送给channel然后读取就会触发，出站处理器只有向channel写入数据才会触发
                        pipeline.addLast("handler1",new ChannelInboundHandlerAdapter(){

                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                ByteBuf buf= (ByteBuf) msg;
                                String s = buf.toString(Charset.defaultCharset());


                                super.channelRead(ctx, s); //fireChannelRead 将处理结果传给h2
                            }
                        }).addLast("handler2",new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                super.channelRead(ctx, msg);
                            }
                        }).addLast("handler3",new ChannelInboundHandlerAdapter(){
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                //向channel中写入数据，触发下面的outbound handler，出站是从尾到头运行(654)，入站是从头到尾(123)
                                //这里调用从pipeline换成ctx
//                                pipeline.writeAndFlush("qweq"); pipeline的writeandflush从尾部开始找
                                //ctx的从当前节点向前找，所以后面的不会执行
                                ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("向channel写入数据触发outbound".getBytes(StandardCharsets.UTF_8)));
//                               /*ctx.channel().write(msg):触发出站处理器执行，从尾部开始查找出站处理器
       //                             ctx.write(msg)：当前节点查找上一个出站处理器（只执行一个？）
//
//                               */
//
//                                super.channelRead(ctx, msg);

                            }
                        }).addLast("hanler4",new ChannelOutboundHandlerAdapter(){
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {

                                super.write(ctx, msg, promise);
                            }
                        });

                    }
                }).bind(8080);
    }
}
